using SmartCommunity.Models;
using Mapster;
using Microsoft.EntityFrameworkCore;

namespace SmartCommunity.Services.Community
{
    /// <summary>
    /// 服务类：社区
    /// </summary>
    public class CommunityService : BaseService<CommunityEntity>
    {
        #region 构造函数
        protected readonly SCDBContext ctx;
        public CommunityService(SCDBContext ctx)
        {
            this.ctx = ctx;
        }
        #endregion

        #region 数据查询 
        /// <summary>
        /// 分页查询
        /// </summary>
        public async Task<PageResult<CommunityDto>> FindPagedList(CommunityQuery communityQuery, Pager pager, LoginUser user)
        {
            //TODO 社区权限
            var query = ctx.Communities.AsNoTracking().Where(communityQuery.GetQueryExpression());
            var data = await FindPagedList(query, pager, o => o.OrderByDescending(t => t.CreatedTime));
            return data.Map(o => o.Adapt<CommunityDto>());
        }

        /// <summary>
        /// 根据社区ID查询
        /// </summary>
        public async Task<CommunityDto> FindCommunityById(Guid communityId)
        {
            var entity = await FindById(communityId);
            return entity.Adapt<CommunityDto>();
        }

        /// <summary>
        /// 根据ID查询实体类
        /// </summary>
        private async Task<CommunityEntity> FindById(Guid id)
        {
            return await ctx.Communities.SingleOrDefaultAsync(a => a.CommunityId == id)
                ?? throw new NotFoundException($"找不到指定的社区,Id:{id}");
        }
        #endregion

        #region 增 删 改
        /// <summary>
        /// 新增社区
        /// </summary>
        public async Task<CommunityDto> CreateCommunity(CommunityDto dto, LoginUser user)
        {
            // 新建对象
            var entity = new CommunityEntity();
            // 复制属性
            await CopyDtoToEntity(dto, entity, user, true);
            // 执行保存
            ctx.Communities.Add(entity);
            await ctx.SaveChangesAsync();
            // 返回Dto
            return entity.Adapt<CommunityDto>();
        }

        /// <summary>
        /// 更新社区
        /// </summary>
        public async Task UpdateCommunity(CommunityDto dto, LoginUser user)
        {
            // 原始数据
            var entity = await FindById(dto.CommunityId);
            var changeName = entity.CommunityName != dto.CommunityName.Trim();
            // 更新字段
            await CopyDtoToEntity(dto, entity, user, false);
            if(changeName)
            {
                ctx.Areas.Where(a=>a.CommunityId==entity.CommunityId).ExecuteUpdate(area => area.SetProperty(b => b.CommunityName, entity.CommunityName));
            }
            // 执行更新
            await ctx.SaveChangesAsync();
        }

        /// <summary>
        /// 复制dto属性到实体字段
        /// </summary>
        private async Task CopyDtoToEntity(CommunityDto dto, CommunityEntity entity, LoginUser user, bool isNew)
        {
            //TODO 检查数据重复
            if (await ctx.Communities.AnyAsync(a => a.CommunityId != dto.CommunityId  && (a.CommunityName == dto.CommunityName.Trim())))
            {
                throw new MessageException("当前已存在相同名称的社区");
            }
            entity.CommunityName = dto.CommunityName.Trim();
            entity.ManagerName = dto.ManagerName;
            entity.ManagerTel = dto.ManagerTel;
            entity.CreatedDate = dto.CreatedDate;
            entity.Disabled = dto.Disabled;
            entity.Remark = dto.Remark;

            // 记录操作人
            if (isNew)
            {
                entity.CreatedBy = user.Username;
                entity.CreatedTime = DateTime.Now;
            }
            entity.UpdatedBy = user.Username;
            entity.UpdatedTime = DateTime.Now;
        }

        /// <summary>
        /// 根据ID删除社区
        /// </summary>
        public async Task DeleteByIds(IEnumerable<Guid> ids, LoginUser user)
        {
            var communities = await ctx.Communities.Include(a=>a.Areas).Where(a => ids.Contains(a.CommunityId)).ToListAsync();
            if (communities.Count != ids.Count())
            {
                throw new MessageException("查询出的数据和传入的ID不匹配，请刷新后再试。");
            }
            // 判断是否能删除
            foreach (var entity in communities)
            {
                if (entity.Areas.Any())
                {
                    throw new MessageException("该社区已存在小区关联，不允许删除。");
                }
                ctx.Communities.Remove(entity);
            }
            // 提交事务
            await ctx.SaveChangesAsync();
        }
        #endregion
    }
}
